package com.flyme.module.base.provider.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.flyme.common.core.model.ResultBody;
import com.flyme.common.core.utils.DateUtils;
import com.flyme.common.core.utils.ObjectUtils;
import com.flyme.common.core.utils.jpush.JpushPush;
import com.flyme.core.base.supper.service.impl.BaseServiceImpl;
import com.flyme.module.base.client.entity.*;
import com.flyme.module.base.provider.mapper.SysBalanceMapper;
import com.flyme.module.base.provider.service.*;
import com.flyme.module.exam.client.entity.BusAbility;
import com.flyme.module.exam.provider.service.BusAbiltityService;
import com.flyme.module.file.client.entity.SysCourse;
import com.flyme.module.file.client.entity.SysCourseEnroll;
import com.flyme.module.file.provider.service.SysCourseEnrollService;
import com.flyme.module.file.provider.service.SysCourseService;
import com.flyme.module.order.client.entity.Order;
import com.flyme.module.order.client.enums.OrderStatusEnum;
import com.flyme.module.order.client.enums.OrderTypeEnum;
import com.flyme.module.order.client.enums.PayStatusEnum;
import com.flyme.module.order.client.enums.PayTypeEnum;
import com.flyme.module.order.provider.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: zyf
 * @date: 2018/10/24 16:33
 * @description:
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class SysBalanceServiceImpl extends BaseServiceImpl<SysBalanceMapper, SysBalance> implements SysBalanceService {

    @Autowired
    private SysBalancelogService balancelogService;
    @Autowired
    private SysBalanceService balanceService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private SysVipService vipService;
    @Autowired
    private SysChargeconfigService chargeconfigService;
    @Autowired
    private SysCourseEnrollService courseenrollService;
    @Autowired
    private BusAbiltityService busAbilityService;
    @Autowired
    private SysBuyrecordService buyrecordService;
    @Autowired
    private SysCourseService courseService;
    @Autowired
    private SysIntegralrecordService integralrecordService;
    @Autowired
    private SysMessageSendService messageSendService;
    @Autowired
    private SysVipPriceService vipPriceService;
    @Autowired
    private SysUserexaminationService sysUserexaminationService;
    @Autowired
    private SysSharelogService sysSharelogService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private SysUserstudyService sysUserstudyService;
    @Autowired
    private SysUsercertificateService sysUsercertificateService;

    @Override
    public SysBalance insert(Long userId) {
        SysBalance balance = new SysBalance();
        balance.setId(userId);
        balance.setAccountInfoId(userId);
        balance.setAmount(new BigDecimal("0"));
        balance.setVersion(1);
        balance.setIntegral(0);
        save(balance);
        return balance;
    }

    @Override
    public ResultBody chargeSuccess(Long balanceId, BigDecimal amount, String outTradeNo) {
        SysBalance balance = getById(balanceId);
        if (ObjectUtils.isNotEmpty(balance)) {
            BigDecimal localAmount = balance.getAmount();
            BigDecimal newAmount = localAmount.add(amount);
            balance.setAmount(newAmount);
            saveOrUpdate(balance);
            balancelogService.insert(balance, outTradeNo, amount, 5, "退款", "");
        } else {
            return ResultBody.failed("未找到你的账户！");
        }
        return ResultBody.ok("账户更新成功");
    }


    @Override
    public SysBalance findByUser(Long accountInfoId) {
        return getOne(q().eq(true, "accountInfoId", accountInfoId), false);
    }

    /**
     * 银联支付成功回调逻辑处理
     */
    public ResultBody unionpay_back(String outTradeNo) {
        Order order = orderService.findByNo(outTradeNo);
        String subject = "";
        String body = "";
        String orderEntity = order.getOrderEntity().getCode();
        if (orderEntity.equals(OrderTypeEnum.vip.code)) {//企业vip购买
            subject = "购买企业vip";
            vipService.addUserVip(order.getUserId(), order.getTargetId());
            body = "scoreCompanyVip";
        }
        order.setOrderStatus(OrderStatusEnum.finish);
        order.setPayStatus(PayStatusEnum.getEnum("PAY_1"));
        order.setPayDate(DateUtil.now());
        boolean save = orderService.saveOrUpdate(order);
        return ResultBody.ok("SUCCESS");
    }

    @Override
    public Boolean addshareLog(String orderId, String body, BigDecimal amount, Long userId, Long sourceUserId, String title) {
        SysSharelog sysSharelog=new SysSharelog();
        sysSharelog.setOrderId(orderId);
        sysSharelog.setAmount(amount);
        sysSharelog.setBody(body);
        sysSharelog.setUserId(userId);
        sysSharelog.setSourceUserId(sourceUserId);
        sysSharelog.setTitle(title);
        return sysSharelogService.save(sysSharelog);
    }

    /**
     * 订单支付成功后回调逻辑处理
     */
    public ResultBody pay_back(Order order) {
        String subject = "";
        String body = "";
        String orderEntity = order.getOrderEntity().getCode();
        if (orderEntity.equals(OrderTypeEnum.vip.code)) {//购买vip
            log.error("=============================================================vip购买回调测试"+order.getOrderEntity());
            subject = "购买vip";
            vipService.addUserVip(order.getUserId(), order.getTargetId());
            SysVipPrice price = vipPriceService.getById(order.getTargetId());
            body = "scoreVip";
            if(price.getScoreVip() > 0){
                getScore(order.getUserId(), body, price.getScoreVip());
            }
            if(ObjectUtils.isNotEmpty(order.getInviteId())){
                SysConfig config= sysConfigService.getByName("shareRatio");
                //订单金额*后台设置比例
                BigDecimal d=new BigDecimal(config.getConfigVal());
                BigDecimal amount=order.getOrderAmount().multiply(d).setScale(2,BigDecimal.ROUND_CEILING);
                addshareLog(String.valueOf(order.getId()),"分享购买会员得奖励",amount,order.getUserId(),order.getInviteId(),"分享购买会员得奖励");
            }
        }
        if (orderEntity.equals(OrderTypeEnum.top_up.code)) {//充值
            subject = "学习币充值";
            SysBalance balance = balanceService.findByUser(order.getUserId());
            SysChargeconfig chargeconfig = chargeconfigService.getById(order.getTargetId());
            balance.setAmount(balance.getAmount().add(chargeconfig.getDiscount()));
            boolean flag = balanceService.updateById(balance);
            if (flag) {//生成账户记录
                balancelogService.insert(balance, "", chargeconfig.getDiscount(), 1, "充值", "充值");
            }
        }
        if (orderEntity.equals(OrderTypeEnum.course.code)) {//课程
            subject = "购买课程";
            SysCourseEnroll courseapply = courseenrollService.applyRecord(order.getTargetId(), order.getUserId(), 1);
            SysCourse course = courseService.getById(order.getTargetId());
            if (ObjectUtils.isNotEmpty(courseapply)) {//用户已经购买过该课程不能重复购买
                return ResultBody.failed("该课程已购买，不能重复购买");
            }
            courseapply = new SysCourseEnroll();
            courseapply.setTargetId(order.getTargetId());
            courseapply.setUserId(order.getUserId());
            courseapply.setApplyType(1);
            courseenrollService.saveOrUpdate(courseapply);
            body = "scoreCourse";
            if(course.getScoreCourse() > 0){
                getScore(order.getUserId(), body, course.getScoreCourse());
            }
            if(ObjectUtils.isNotEmpty(order.getInviteId())){
                SysConfig config= sysConfigService.getByName("shareRatio");
                //订单金额*后台设置比例
                BigDecimal d=new BigDecimal(config.getConfigVal());
                BigDecimal amount=order.getOrderAmount().multiply(d).setScale(2,BigDecimal.ROUND_CEILING);
                addshareLog(String.valueOf(order.getId()),"分享购买课程得奖励",amount,order.getUserId(),order.getInviteId(),"分享购买课程得奖励");
            }
        }
        if (orderEntity.equals(OrderTypeEnum.offcourse.code)) {//线下课程
            subject = "购买线下课程";
            SysCourseEnroll courseapply = courseenrollService.applyRecord(order.getTargetId(), order.getUserId(), 3);
            if (ObjectUtils.isNotEmpty(courseapply)) {//用户已经购买过该课程不能重复购买
                return ResultBody.failed("该课程已购买，不能重复购买");
            }
            courseapply = new SysCourseEnroll();
            courseapply.setTargetId(order.getTargetId());
            courseapply.setUserId(order.getUserId());
            courseapply.setApplyType(3);
            courseenrollService.saveOrUpdate(courseapply);
            body = "scoreCourse";
            if(ObjectUtils.isNotEmpty(order.getInviteId())){
                SysConfig config= sysConfigService.getByName("shareRatio");
                //订单金额*后台设置比例
                BigDecimal d=new BigDecimal(config.getConfigVal());
                BigDecimal amount=order.getOrderAmount().multiply(d).setScale(2,BigDecimal.ROUND_CEILING);
                addshareLog(String.valueOf(order.getId()),"分享购买线下课程得奖励",amount,order.getUserId(),order.getInviteId(),"分享购买线下课程得奖励");
            }
        }
        if (orderEntity.equals(OrderTypeEnum.live.code)) {//直播报名
            subject = "直播报名";
            SysCourseEnroll courseapply = courseenrollService.applyRecord(order.getTargetId(), order.getUserId(), 2);
            if (ObjectUtils.isNotEmpty(courseapply)) {//用户已经购买过该课程不能重复购买
                return ResultBody.failed("该直播已报名，不能重复报名");
            }
            courseapply = new SysCourseEnroll();
            courseapply.setTargetId(order.getTargetId());
            courseapply.setUserId(order.getUserId());
            courseapply.setApplyType(2);
            courseenrollService.saveOrUpdate(courseapply);
        }
        if (orderEntity.equals(OrderTypeEnum.examnation.code)) {//考试报名
            subject = "考试报名";
            SysUserexamination userexamination = sysUserexaminationService.getById(order.getTargetId());
            sysUserexaminationService.updateSysuserexam(userexamination.getId());
            if(ObjectUtils.isNotEmpty(order.getInviteId())){
                SysConfig config= sysConfigService.getByName("shareRatio");
                //订单金额*后台设置比例
                BigDecimal d=new BigDecimal(config.getConfigVal());
                BigDecimal amount=order.getOrderAmount().multiply(d).setScale(2,BigDecimal.ROUND_CEILING);
                addshareLog(String.valueOf(order.getId()),"分享报名考试奖励",amount,order.getUserId(),order.getInviteId(),"分享报名考试奖励");
            }
        }
        if (orderEntity.equals(OrderTypeEnum.studycourse.code)) {
            subject = "继续教育"; //继续教育回调业务逻辑处理
            SysUserstudy sysUserstudy=sysUserstudyService.findnoPay(order.getTargetId());
            if(ObjectUtils.isNotEmpty(sysUserstudy)){
                sysUserstudy.setStatus("1");
                sysUserstudy.setPayTime(DateUtils.getDateTime());
                sysUserstudyService.saveOrUpdate(sysUserstudy);
            }
        }
        if (orderEntity.equals(OrderTypeEnum.appraisal.code)) {//能力测评
            BusAbility ability = busAbilityService.findAbility();
            SysBuyrecord buyrecord = buyrecordService.getByUser2(order.getUserId());
            if (ObjectUtils.isEmpty(buyrecord)) {//没有购买
                buyrecord = new SysBuyrecord();
                buyrecord.setAccountInfoId(order.getUserId());
                buyrecord.setAbilityId(String.valueOf(ability.getId()));
                buyrecord.setExpireTime(DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.date(), Integer.valueOf(ability.getExpireTime()))));
            } else {//购买过
                boolean s = DateUtil.isExpired(DateUtil.parseDateTime(buyrecord.getExpireTime()), DateField.DAY_OF_YEAR, Integer.valueOf(ability.getExpireTime()), DateUtil.date());
                if (s) {//续费
                    String expiryDate = DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.parseDateTime(buyrecord.getExpireTime()), Integer.valueOf(ability.getExpireTime())));
                    buyrecord.setExpireTime(expiryDate);
                }
                buyrecord.setExpireTime(DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.date(), Integer.valueOf(ability.getExpireTime()))));
            }
            buyrecordService.saveOrUpdate(buyrecord);
        }
        order.setOrderStatus(OrderStatusEnum.finish);
        order.setPayStatus(PayStatusEnum.getEnum("PAY_1"));
        order.setPayDate(DateUtil.now());
        boolean save = orderService.saveOrUpdate(order);
        if (save) {
            JpushPush jPush = new JpushPush();
            Map<String, String> msg = new HashMap<String, String>();
            List<String> aliases = new ArrayList<>();
            aliases.add(order.getUserId().toString());
            String pushMsg = "您的订单已支付成功，请在订单详情中查看";
            //发送推送
            msg.put("msg", pushMsg);
            msg.put("pushType", "2");
            msg.put("content", pushMsg);
            msg.put("orderId", String.valueOf(order.getId()));
            jPush.pushByAlias("COMM", aliases, pushMsg, "2", order.getUserId().toString(), msg);
            SysMessageSend messageSend = new SysMessageSend();
            messageSend.setMessageStatus(0);
            messageSend.setUserId(order.getUserId());
            messageSend.setTargetId(String.valueOf(order.getId()));
            messageSend.setMessageType("2");
            messageSendService.save(messageSend);
        }
        return ResultBody.ok("SUCCESS");
    }

    public void getScore(Long accountId, String name, Integer score) {
        SysIntegralrecord integralrecord = new SysIntegralrecord();
        integralrecord.setAccountId(accountId);
        integralrecord.setRecordCode(name);
        integralrecord.setIntegral(score);
        if ("scoreVip".equals(name)) {
            integralrecord.setRecordBody("购买个人vip");
        }
        if ("scoreCompanyVip".equals(name)) {
            integralrecord.setRecordBody("购买企业vip");
        }
        if ("scoreCourse".equals(name)) {
            integralrecord.setRecordBody("购买课程");
        }
        integralrecordService.save(integralrecord);
        SysBalance balance = balanceService.getById(accountId);
        //初始化余额表有可能小程序没有添加数据
        if(ObjectUtils.isNotEmpty(balance)){
            balance.setIntegral(balance.getIntegral() + score);
            balanceService.saveOrUpdate(balance);
        }
    }

    /**
     * 学习币及线下支付
     */
    public ResultBody payBack(String orderId, String payType) {
        Order order = orderService.getById(orderId);
        if (!order.getOrderStatus().equals(OrderStatusEnum.unpaid)) {
            return ResultBody.failed("该订单不是未支付状态");
        }
        order.setPayType(PayTypeEnum.getEnum(payType));
        if (payType.equals(PayTypeEnum.offline.code)) {//线下支付（线下支付不更新payinfo状态和order支付状态）
            orderService.saveOrUpdate(order);
            return ResultBody.ok("操作成功");
        }
        if (payType.equals(PayTypeEnum.Balance.code)) {//学习币支付
            SysBalance balance = findByUser(order.getUserId());
            if (balance.getAmount().compareTo(order.getOrderAmount()) < 0) {
                return ResultBody.failed("学习币不足，请充值");
            }
            ResultBody resultBody = pay_back(order);
            if (resultBody.getStatus()) {
                balance = balance.setAmount(balance.getAmount().subtract(order.getOrderAmount()));
                UpdateWrapper u = new UpdateWrapper();
                update(u.set(true, "amount", balance.getAmount()).eq(true, "id", balance.getId()));
                balancelogService.insert(balance, orderId, order.getOrderAmount(), 2, "消费", "消费");
            } else {
                return resultBody;
            }
        }
        return ResultBody.ok("支付成功");
    }

}
